package com.yeyks.common.utils.apputil;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

/**
 * @author dell
 */
@Component
@Slf4j
public class RedisLockUtil {

	private StringRedisTemplate redisTemplate;

	@Autowired
	public RedisLockUtil(StringRedisTemplate redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	/**
	 * 加锁
	 * @param key 键
	 * @param value 当前时间 加 过期时间
	 * @return
	 */
	public Boolean lock(String key, String value){

		if(redisTemplate.opsForValue().setIfAbsent(key,value)){
			return true;
		}
        //解决死锁的问题 如 currentValue 为 A  然后两个线程的value 都为 B , 其中只有一个能拿到锁
		String currentValue = redisTemplate.opsForValue().get(key);
		//如果锁过期
		if(StringUtils.isNotEmpty(currentValue) &&
				Long.parseLong(currentValue) < System.currentTimeMillis()){
			//获取上一个锁的时间
			String oldValue = redisTemplate.opsForValue().getAndSet(key,value);
			if(StringUtils.isNotEmpty(oldValue) && oldValue.equals(currentValue)){
				return true;
			}
		}
		return false;
	}

	/**
	 * 解锁(删除Key)
	 * @param key 键
	 * @param value  当前时间 加 过期时间
	 */
	public void unlock(String key, String value){
        //可能出现异常
		try {
			String currentValue = redisTemplate.opsForValue().get(key);
			if(StringUtils.isNotEmpty(currentValue) && currentValue.equals(value)){
				redisTemplate.opsForValue().getOperations().delete(key);
			}
		}catch (Exception e){
			log.info("[redis解锁异常] {}:",e);
		}
	}

}
